package com.quanyan.place.interceptor;

import com.quanyan.common.utils.GsonUtils;
import com.quanyan.common.utils.ObjectUtil;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.Properties;

/**
 * Created by youxiaojia on 2017/4/5.
 * 数据库写操作拦截器
 */
@Intercepts({@Signature(method = "update", type = Executor.class, args = {MappedStatement.class, Object.class})})
public class LogInterceptor implements Interceptor {

    private static Logger logger = LoggerFactory.getLogger("writeDbLog");

    private Properties properties;

    @Pointcut("execution(* com.quanyan..service.*Service.*(..))")
    public void service() {
    }

    @Override
    @Around(value = "service()")
    public Object intercept(Invocation invocation) throws Throwable {
        Object result = null;
        //Object[] args = invocation.getArgs();
       /* if (args.length > 1) {
            // 传入的对象
            Object obj = args[1];
            try{
                saveLog(args[0], obj, "success");

            }catch (Exception e){
                saveLog(args[0], obj, ObjectUtil.getFullStackTraceToString(e));
            }
        }*/
        result = invocation.proceed();
        return result;
    }

    private void saveLog(Object arg, Object obj, String executeResult) {
        Log log = new Log();
        log.setExecuteResult(executeResult);
        log.setCreateTime(new Date());
        log.setModifyTime(new Date());
        MappedStatement mappedStatement = (MappedStatement) arg;
        // 执行的方法名
        String name = mappedStatement.getSqlCommandType().name();
        String change = GsonUtils.toJson(obj);
        log.setSql(mappedStatement.getSqlSource().getBoundSql(obj).getSql());
        if (name.startsWith("INSERT")) {
            log.setType("新增" + obj.getClass().getSimpleName());
            log.setNewContent(change);
        } else if (name.startsWith("UPDATE")) {
            log.setType("修改" + obj.getClass().getSimpleName());
            log.setNewContent(change);
        }/* else if (name.startsWith("DELETE")) {
            log.setType("删除" + obj.getClass().getSimpleName());
            log.setOldContent(change);
        }*/
        logger.info(GsonUtils.toJson(log));
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    class Log {
        private Date createTime;
        private Date modifyTime;
        private String type;
        private String sql;
        private String oldContent;
        private String newContent;
        private String executeResult;

        public Date getCreateTime() {
            return createTime;
        }

        public void setCreateTime(Date createTime) {
            this.createTime = createTime;
        }

        public Date getModifyTime() {
            return modifyTime;
        }

        public void setModifyTime(Date modifyTime) {
            this.modifyTime = modifyTime;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getSql() {
            return sql;
        }

        public void setSql(String sql) {
            this.sql = sql;
        }

        public String getOldContent() {
            return oldContent;
        }

        public void setOldContent(String oldContent) {
            this.oldContent = oldContent;
        }

        public String getNewContent() {
            return newContent;
        }

        public void setNewContent(String newContent) {
            this.newContent = newContent;
        }

        public String getExecuteResult() {
            return executeResult;
        }

        public void setExecuteResult(String executeResult) {
            this.executeResult = executeResult;
        }
    }
}

